/*
 * graph2D
 * Copyright (c) 2009 Shun Moriya <shun@mnu.sakura.ne.jp>
 *
 * The MIT License
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#if !defined(___GRAPHC2D_SCENE_H___)
#define ___GRAPHC2D_SCENE_H___

#include "container.h"
#include "window.h"
#include "particleManager.h"
#include "variableContainer.h"
#include "vector2.h"
#include <mana.h>

#define DEFAULT_FADE_TIME	0.5f
#define MESSAGE_LAYER		1

namespace Graph2D
{
	class MessageWindow;
	class TextWindow;
	class ParticleManager;

	/*!
	 * @brief	シーンクラス
	 */
	class Scene : public VariableContainer
	{
		DISALLOW_COPY_AND_ASSIGN(Scene);

		typedef VariableContainer super;

	public:
		/*!
		 * @brief		コンストラクタ
		 * @param[in]	sceneType	シーン識別子
		 */
		Scene(const unsigned int sceneType = ~0);

		/*!
		 * @brief	デストラクタ
		 */
		virtual ~Scene();

		/*!
		 * @brief	タイプ名を取得
		 * @return	タイプ名
		 */
		virtual const char* getTypeName() const
		{
			return "Scene";
		}

		/*!
		 * @brief	シーン識別子を取得
		 * @return	シーン識別子
		 */
		unsigned int getSceneType() const
		{
			return sceneType;
		}

		/*!
		 * @brief	シーン名を取得
		 * @return	シーン名
		 */
		virtual const char* getSceneName() const
		{
			return "DefaultScene";
		}

		/*!
		 * @brief	ステート番号を取得
		 * @return	ステート番号
		 */
		unsigned int getState() const
		{
			return state;
		}

		/*!
		 * @brief		ステート番号を設定
		 * @param[in]	ステート番号
		 */
		void setState(const unsigned int state);

		MessageWindow* getMessageWindow();
		const MessageWindow* getMessageWindow() const
		{
			return getMessageWindow();
		}

		TextWindow* getTextWindow();
		const TextWindow* getTextWindow() const
		{
			return getTextWindow();
		}

		Container* getDialog()
		{
			return dialog;
		}
		const Container* getDialog() const
		{
			return getDialog();
		}
		void setDialog(Container* dialog, const bool centering);

		ParticleManager* getParticleManager();

		float fadein(const float second = DEFAULT_FADE_TIME) const;
		float fadeout(const float second = DEFAULT_FADE_TIME) const;

		bool loadScript(const std::string& filename);	//!< スクリプトを読み込みます
		void unloadScript();							//!< スクリプトを開放します
		mana* getScript();								//!< スクリプトを取得します

		virtual void onSerialize(mana_stream* stream) const;
		virtual void onDeserialize(mana_stream* stream);
		virtual void onDestroy(Component* component);
		virtual void onUpdate(const UpdateInfomation& updateInfomation);
		virtual bool onDraw(const DrawRect& drawRect);

		virtual bool touchesBegan(const Vector2& localPosition);
		virtual bool touchesMoved(const Vector2& localPosition);
		virtual bool touchesEnded(const Vector2& localPosition);
		virtual bool touchesCancelled(const Vector2& localPosition);

		virtual bool onPrepare()
		{
			return true;
		}
		virtual void onInitialize(){}
		virtual void onFinalize(){}

		virtual bool compare(const Scene& other) const;

	protected:
		void fade(const float alpha, const float second = 0.8f);

	protected:
		unsigned int sceneType;
		unsigned int state;

		MessageWindow* messageWindow;
		TextWindow* textWindow;

		Container* dialog;
		float fadeColor;
		float fadeDeltaColor;
		float fadeTargetColor;
		float fadeColorTime;
		bool fadeColorEnable;

		ParticleManager* particleManager;

		std::string scriptProgramFileName;		//!< スクリプトファイル名
		Data* scriptProgram;					//!< スクリプト実行プログラム
		mana* script;							//!< スクリプト
	};
}

#endif
